package org.jacp.demo.util;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.Border;

import com.explodingpixels.border.FocusStateMatteBorder;
import com.explodingpixels.macwidgets.BottomBarSize;
import com.explodingpixels.macwidgets.MacColorUtils;
import com.explodingpixels.painter.FocusStatePainter;
import com.explodingpixels.painter.GradientPainter;
import com.explodingpixels.painter.Painter;
import com.explodingpixels.util.PlatformUtils;
import com.explodingpixels.widgets.WindowUtils;

public class BottomBar extends JPanel {

    /**
     * 
     */
    private static final long serialVersionUID = 2147708535060227770L;
    private static final Color ACTIVE_TOP_COLOR = UIManager.getColor("Button.light");//new Color(0xcccccc);
    private static final Color ACTIVE_BOTTOM_COLOR = UIManager.getColor("Button.highlight");//new Color(0xa7a7a7);
    private static final Color INACTIVE_TOP_COLOR = new Color(0xe9e9e9);
    private static final Color INACTIVE_BOTTOM_COLOR = new Color(0xd8d8d8);
    private static final Color BORDER_HIGHLIGHT_COLOR = UIManager.getColor("SplitPane.shadow");

    private static final Color LEOPARD_ACTIVE_TOP_COLOR = new Color(0xbbbbbb);
    private static final Color LEOPARD_ACTIVE_BOTTOM_COLOR = new Color(0x969696);
    private static final Color LEOPARD_INACTIVE_TOP_COLOR = new Color(0xe3e3e3);
    private static final Color LEOPARD_INACTIVE_BOTTOM_COLOR = new Color(
	    0xcfcfcf);
    private static final Color LEOPARD_BORDER_HIGHLIGHT_COLOR = new Color(255,
	    255, 255, 110);

    private Painter<Component> fBackgroundPainter;

    public BottomBar(final BottomBarSize size) {
	super();
	init(size);
    }

    public BottomBar(final int hint, final BottomBarSize size) {
	super();
	setLayout(new FlowLayout(hint, 5, 1));
	init(size);

    }

    private void init(final BottomBarSize size) {
	setOpaque(false);

	setBackgroundPainter(PlatformUtils.isLeopard() ? createLeopardPainter()
		: createDefaultPainter());
	createAndInstallBorder();

	// TODO use the actual border insets instead of the hard-coded value 2.
	// calculate the height of the bottom bar. this includes adding two
	// pixels to incorporate
	// the height of the line border.
	final int height = size.getHeight() + 2;
	setPreferredSize(new Dimension(-1, height));

	// install a listener that will repaint this component when the parent
	// window's focus state
	// changes.
	WindowUtils.installJComponentRepainterOnWindowFocusChanged(this);
    }

    private void createAndInstallBorder() {
	final FocusStateMatteBorder outterBorder = new FocusStateMatteBorder(1,
		0, 0, 0,
		MacColorUtils.getTexturedWindowToolbarBorderFocusedColor(),
		MacColorUtils.getTexturedWindowToolbarBorderUnfocusedColor(),
		this);
	final Border innerBorder = BorderFactory.createMatteBorder(1, 0, 0, 0,
		getBorderHighlightColor());
	final Border lineBorders = BorderFactory.createCompoundBorder(
		outterBorder, innerBorder);

	// TODO determine if there is a good standard for this. there doesn't
	// seem to be any
	// TODO consistent value used by Apple.
	// left and right edge padding.
	final int padding = 3;
	setBorder(BorderFactory.createCompoundBorder(lineBorders,
		BorderFactory.createEmptyBorder(0, padding, 0, padding)));
    }

    public void setBackgroundPainter(final Painter<Component> painter) {
	fBackgroundPainter = painter;
    }

    @Override
    protected void paintComponent(final Graphics g) {
	if (fBackgroundPainter != null) {
	    final Graphics2D graphics2D = (Graphics2D) g.create();
	    fBackgroundPainter.paint(graphics2D, this, getWidth(), getHeight());
	    graphics2D.dispose();
	}

	// TODO see if we can get rid of this call to super.paintComponent.
	super.paintComponent(g);
    }

    private static Painter<Component> createDefaultPainter() {
	final Painter<Component> focusedPainter = new GradientPainter(
		ACTIVE_TOP_COLOR, ACTIVE_BOTTOM_COLOR);
	final Painter<Component> unfocusedPainter = new GradientPainter(
		INACTIVE_TOP_COLOR, INACTIVE_BOTTOM_COLOR);
	return new FocusStatePainter(focusedPainter, focusedPainter,
		unfocusedPainter);
    }

    private static Painter<Component> createLeopardPainter() {
	final Painter<Component> focusedPainter = new GradientPainter(
		LEOPARD_ACTIVE_TOP_COLOR, LEOPARD_ACTIVE_BOTTOM_COLOR);
	final Painter<Component> unfocusedPainter = new GradientPainter(
		LEOPARD_INACTIVE_TOP_COLOR, LEOPARD_INACTIVE_BOTTOM_COLOR);
	return new FocusStatePainter(focusedPainter, focusedPainter,
		unfocusedPainter);
    }

    private static Color getBorderHighlightColor() {
	return PlatformUtils.isLeopard() ? LEOPARD_BORDER_HIGHLIGHT_COLOR
		: BORDER_HIGHLIGHT_COLOR;
    }

}
